home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include "netconf.h"
- #include <netdb.h>
- #include "../userconf/userconf.h"
- #include "netconf.m"
-
- static NETCONF_HELP_FILE help_rarp ("rarp");
- static CONFIG_FILE f_net_rarp (PROC_NET_RARP
- ,help_rarp
- ,CONFIGF_OPTIONNAL|CONFIGF_PROBED);
-
-
- class RARP_ENTRY: public ARRAY_OBJ{
- public:
- char seen; // Used to tell if one entry has been
- // processed
- char active; // This record has to be activated in the kernel
- SSTRING ip; // IP number of host name
- SSTRING hw; // Hardware address
- SSTRING comment;
- /*~PROTOBEG~ RARP_ENTRY */
- public:
- RARP_ENTRY (const char *_ip,
- const char *_hw,
- int _active,
- const char *_comment);
- RARP_ENTRY (const char *str, int noline);
- RARP_ENTRY (void);
- int cmp (const char *ipstr);
- int edit (void);
- int is_valid (int talk);
- private:
- int normalise (void);
- public:
- int set (void);
- int unset (void);
- /*~PROTOEND~ RARP_ENTRY */
- };
- /*
- Constructor used to read /proc/net/rarp
- */
- PUBLIC RARP_ENTRY::RARP_ENTRY(const char *str, int noline)
- {
- active = 1;
- seen = 0;
- char ipstr[100];
- char mbps[100];
- char ethernet[100];
- char hwstr[100];
- /* #Specification: rarp / proc/net/rarp / format
- We assume this file has the following format
- and are simply looking for 4 words.
-
- #
- ip_number 10Mbps Ethernet hw_address
- #
-
- We are validating the second and third word to make sure
- */
- if (sscanf (str,"%s %s %s %s",ipstr,mbps,ethernet,hwstr)==4){
- if (strcmp(mbps,"10Mbps")!=0
- || strcmp(ethernet,"Ethernet")!=0){
- xconf_error (MSG_U(E_IVLDRARPFORM
- ,"Invalid format in file %s, line %d")
- ,f_net_rarp.getpath(),noline);
- }else{
- ip.setfrom (ipstr);
- hw.setfrom (hwstr);
- }
- }
- }
-
- /*
- Constructor used to read configuration.
- */
- PUBLIC RARP_ENTRY::RARP_ENTRY(
- const char *_ip,
- const char *_hw,
- int _active,
- const char *_comment)
- {
- seen = 0;
- ip.setfrom (_ip);
- hw.setfrom (_hw);
- active = (char)_active;
- comment.setfrom (_comment);
- normalise();
- }
-
- /*
- Create an empty entry
- */
- PUBLIC RARP_ENTRY::RARP_ENTRY()
- {
- seen = 0;
- active = 1;
- }
-
- /*
- Add this entry to the rarp table
- */
- PUBLIC int RARP_ENTRY::set()
- {
- char buf[200];
- sprintf (buf,"-s %s %s",ip.get(),hw.get());
- return netconf_system_if ("rarp",buf);
- }
-
- /*
- Compare one IP number with this entry
- Return 0 if equal, != 0 if different.
- */
- PUBLIC int RARP_ENTRY::cmp(const char *ipstr)
- {
- int ret = ip.cmp(ipstr);
- if (ret != 0){
- /* #Specification: rarp / entry / ip or host name
- We can specify a host either by its IP number
- or its host name.
- */
- struct hostent *ent = gethostbyname(ip.get());
- if (ent != NULL){
- char str[20];
- devices_ip2a (ent,str);
- ret = strcmp(ipstr,str);
- }
- }
- return ret;
- }
-
-
-
- /*
- delete this entry from the rarp table
- */
- PUBLIC int RARP_ENTRY::unset ()
- {
- char buf[200];
- sprintf (buf,"-d %s",ip.get());
- return netconf_system_if ("rarp",buf);
- }
-
-
- class RARP_ENTRIES: public ARRAY{
- /*~PROTOBEG~ RARP_ENTRIES */
- public:
- RARP_ENTRIES (CONFIG_FILE&f);
- RARP_ENTRIES (void);
- void edit (void);
- RARP_ENTRY *getitem (int no);
- int isoneactive (void);
- RARP_ENTRY *locate (const char *ipstr);
- int save (void);
- void update (RARP_ENTRIES¤t);
- /*~PROTOEND~ RARP_ENTRIES */
- };
-
- PUBLIC RARP_ENTRY *RARP_ENTRIES::getitem (int no)
- {
- return (RARP_ENTRY*)ARRAY::getitem(no);
- }
-
- /*
- Locate an entry using its IP number or name.
- Only active entries are checked.
- */
- PUBLIC RARP_ENTRY *RARP_ENTRIES::locate (const char *ipstr)
- {
- RARP_ENTRY *ret = NULL;
- for (int i=0; i<getnb(); i++){
- RARP_ENTRY *a = getitem(i);
- if (a->active && a->cmp(ipstr)==0){
- ret = a;
- break;
- }
- }
- return ret;
- }
-
- static char RARP[]="rarp";
- static char ENTRY[]="entry";
- /*
- Load from /etc/conf.linuxconf
- */
- PUBLIC RARP_ENTRIES::RARP_ENTRIES()
- {
- SSTRINGS strs;
- linuxconf_getall (RARP,ENTRY,strs,0);
- int nb = strs.getnb();
- for (int i=0; i<nb; i++){
- SSTRING *s = strs.getitem(i);
- char ipstr[200],hwstr[200],acstr[200];
- const char *pt = s->get();
- pt = str_copyword (ipstr,pt);
- pt = str_copyword (hwstr,pt);
- pt = str_copyword (acstr,pt);
- // The active field has been added. It defaults to "active"
- int active = acstr[0] == '\0' ? 1 : atoi(acstr) != 0;
- pt = str_skip(pt);
- sscanf (s->get(),"%s %s",ipstr,hwstr);
- add (new RARP_ENTRY (ipstr,hwstr,active,pt));
- }
- rstmodified();
- }
-
- /*
- Update /etc/conf.linuxconf
- */
- PUBLIC int RARP_ENTRIES::save()
- {
- int n = getnb();
- linuxconf_removeall (RARP,ENTRY);
- for (int i=0; i<n; i++){
- RARP_ENTRY *e = getitem(i);
- char buf[400];
- sprintf (buf,"%s %s %d %s",e->ip.get(),e->hw.get(),e->active
- ,e->comment.get());
- linuxconf_add (RARP,ENTRY,buf);
- }
- rstmodified();
- return linuxconf_save();
- }
-
- /*
- Load the running config.
- */
- PUBLIC RARP_ENTRIES::RARP_ENTRIES(CONFIG_FILE &f)
- {
- FILE *fin = f.fopen ("r");
- if (fin != NULL){
- int noline = 1;
- char buf[300];
- // Skip the first line
- fgets (buf,sizeof(buf)-1,fin);
- while (fgets (buf,sizeof(buf)-1,fin) != NULL){
- noline++;
- add (new RARP_ENTRY(buf,noline));
- }
- fclose (fin);
- }
- }
-
-
- PUBLIC void RARP_ENTRIES::update (RARP_ENTRIES ¤t)
- {
- int n = current.getnb();
- int i;
- for (i=0; i<n; i++){
- RARP_ENTRY *cur_a = current.getitem(i);
- RARP_ENTRY *a = locate (cur_a->ip.get());
- if (a == NULL){
- cur_a->unset();
- }else{
- a->seen = 1;
- if (a->hw.cmp(cur_a->hw)!=0){
- cur_a->unset();
- a->set();
- }
- }
- }
- n = getnb();
- for (i=0; i<n; i++){
- RARP_ENTRY *a = getitem(i);
- if (!a->seen && a->active) a->set();
- }
- }
-
- /*
- Validate and normalise the format of the hardware address.
- Make sure there is 2 digits per byte. This helps when comparing
- with the current setup as read from /proc/net/rarp.
- */
- PRIVATE int RARP_ENTRY::normalise()
- {
- int digits[6];
- memset (digits,0,sizeof(digits));
- const char *pt = hw.get();
- int err = 0;
- int nbhex = 0;
- int nbpt = 0;
- while (*pt != '\0'){
- char carac = *pt++;
- if (carac == ':'){
- if (nbhex == 0 || nbhex > 2) err = 1;
- nbhex = 0;
- nbpt++;
- }else if (nbpt == 6){
- err = 1;
- }else if (isxdigit(carac)){
- digits[nbpt] *= 16;
- if (isalpha(carac)){
- carac = toupper(carac) - 'A' + 10;
- }else{
- carac -= '0';
- }
- digits[nbpt] += carac;
- nbhex++;
- }else{
- err = 1;
- }
- }
- if (nbpt != 5 || nbhex == 0){
- err = 1;
- }else{
- char formstr[6*2+5+0];
- sprintf (formstr,"%02x:%02x:%02x:%02x:%02x:%02x"
- ,digits[0],digits[1],digits[2],digits[3],digits[4],digits[5]);
- hw.setfrom (formstr);
- }
- return err ? -1 : 0;
- }
-
- /*
- Return != 0 the entry is valid.
- May operate silently or show errors
- */
- PUBLIC int RARP_ENTRY::is_valid(int talk)
- {
- int ret = 0;
- if (ip.is_empty() || hw.is_empty()){
- if (talk) xconf_error (MSG_U(E_ALLFIELD,"All field must be filled"));
- }else{
- if (normalise()==-1){
- if (talk){
- xconf_error (MSG_U(E_HARDETH
- ,"Invalid hardware ethernet address\n"
- "%s\n"
- "Expect xx:xx:xx:xx:xx:xx format")
- ,hw.get());
- }
- }else{
- ret = 1;
- }
- }
- return ret;
- }
- /*
- Edit one entry
- Return -1 if the user cancel
- Return 0 if the user accept the changes
- Return 1 if the user wish to delete this record
- */
- PUBLIC int RARP_ENTRY::edit()
- {
- int ret = -1;
- DIALOG dia;
- dia.newf_chk ("",active,MSG_U(F_RARPACTIVE,"This record is active"));
- dia.newf_str (MSG_U(F_HOSTNAME,"host name or IP number"),ip);
- dia.newf_str (MSG_U(F_ETHADR,"Ethernet address"),hw);
- dia.newf_str (MSG_R(F_COMMENT),comment);
- int nof = 0;
- while (1){
- MENU_STATUS code = dia.edit(MSG_U(T_ETH2IP,"Ethernet to IP translation")
- ,MSG_U(I_ETH2IP
- ,"Enter an IP number or a host name\n"
- "and its ethernet 6 hexadecimal digit\n"
- "address")
- ,help_rarp
- ,nof
- ,MENUBUT_CANCEL|MENUBUT_ACCEPT|MENUBUT_DEL);
- if (code == MENU_CANCEL || code == MENU_ESCAPE){
- break;
- }else if (code == MENU_DEL){
- ret = 1;
- break;
- }else if (is_valid(1)){
- ret = 0;
- break;
- }
- }
- if (ret != 0) dia.restore();
- return ret;
- }
-
- static int cmp_by_ip (const ARRAY_OBJ *o1, const ARRAY_OBJ *o2)
- {
- RARP_ENTRY *e1 = (RARP_ENTRY*)o1;
- RARP_ENTRY *e2 = (RARP_ENTRY*)o2;
- return e1->ip.cmp(e2->ip);
- }
-
- PUBLIC void RARP_ENTRIES::edit()
- {
- int choice = 0;
- while (1){
- DIALOG dia;
- sort (cmp_by_ip);
- for (int i=0; i<getnb(); i++){
- RARP_ENTRY *e = getitem(i);
- char buf1[30],buf2[100];
- sprintf (buf1,"[%c] %s",e->active ? 'X' : ' ',e->ip.get());
- sprintf (buf2,"%s %s",e->hw.get(),e->comment.get());
- dia.new_menuitem (buf1,buf2);
- }
- dia.addwhat (MSG_U(I_ANEWENTRY,"a new entry"));
- MENU_STATUS code = dia.editmenu(
- MSG_U(T_RARPCONF,"RARP configuration")
- ,MSG_U(I_RARPCONF,"You are allowed to edit/add\n"
- "RARP (Reverse Address Resolution)\n"
- "which will allow other computer to get\n"
- "their IP number from this server\n")
- ,help_rarp
- ,choice
- ,0);
- if (code == MENU_ESCAPE || code == MENU_QUIT){
- break;
- }else if (perm_rootaccess(MSG_U(P_EDITRARP
- ,"to edit RARP configuration"))){
- if (code == MENU_ADD){
- RARP_ENTRY *e = new RARP_ENTRY;
- if (e->edit () == 0){
- add (e);
- save();
- }else{
- delete e;
- }
- }else if (choice >= 0 && choice < getnb()){
- RARP_ENTRY *e = getitem(choice);
- if (code == MENU_OK){
- int ok = e->edit();
- if (ok >= 0){
- if (ok == 1) remove_del (e);
- save();
- }
- }
- }
- }
- }
- }
- /*
- Return != 0 if there is at least one record active
- */
- PUBLIC int RARP_ENTRIES::isoneactive()
- {
- int ret = 0;
- int n = getnb();
- for (int i=0; i<n; i++){
- RARP_ENTRY *e = getitem(i);
- if (e->active){
- ret = 1;
- break;
- }
- }
- return ret;
- }
-
- /*
- Edit the RARP table used to program the kernel RARP table
- */
- void rarp_edit()
- {
- RARP_ENTRIES rarps;
- rarps.edit();
- }
-
-
- /*
- Install, update the rarp table
- */
- void rarp_activate ()
- {
- if (perm_rootaccess(MSG_U(P_UPDRARP,"to install RARP entry"))){
- RARP_ENTRIES conf;
- if (f_net_rarp.exist()){
- RARP_ENTRIES cur (f_net_rarp);
- conf.update (cur);
- }else if (conf.isoneactive()){
- /* #Specification: rarp / module
- If /proc/net/rarp is not available, the command
- "modprobe rarp" is executed to load the module.
- The presence of /proc/net/rarp is checked again
- to see if it has succeeded. An error message is
- generated.
-
- This is done only if some rarp entries are
- configured.
- */
- netconf_system_if ("modprobe","rarp");
- if (f_net_rarp.exist()){
- RARP_ENTRIES cur (f_net_rarp);
- conf.update (cur);
- }else{
- xconf_error (MSG_U(E_NORARP
- ,"This kernel does not support RARP\n"
- "I can't load the RARP table\n"
- "Some machines may fail to boot because of that"));
- }
- }
- }
- }
-